package com.yanfan.maintain.service.impl;

import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.yanfan.attach.domain.DeviceDetail;
import com.yanfan.attach.mapper.DeviceDetailMapper;
import com.yanfan.common.core.domain.AjaxResult;
import com.yanfan.common.core.domain.entity.SysRole;
import com.yanfan.common.core.domain.entity.SysUser;
import com.yanfan.common.core.redis.RedisCache;
import com.yanfan.common.exception.base.BaseException;
import com.yanfan.common.utils.SecurityUtils;
import com.yanfan.common.utils.StringUtils;
import com.yanfan.energy.domain.*;
import com.yanfan.energy.domain.enums.BatchesStatus;
import com.yanfan.energy.domain.enums.DeviceManageEnums;
import com.yanfan.energy.domain.enums.TimeDimensionEnum;
import com.yanfan.energy.domain.enums.WorkOrderStatus;
import com.yanfan.energy.domain.model.ComboBoxBody;
import com.yanfan.energy.util.DateUtils;
import com.yanfan.iot.cache.IThingModelCache;
import com.yanfan.iot.domain.DeviceLifecyle;
import com.yanfan.iot.domain.Group;
import com.yanfan.iot.domain.Product;
import com.yanfan.iot.service.IGroupService;
import com.yanfan.iot.service.IProductService;
import com.yanfan.iot.service.IThingsModelService;
import com.yanfan.maintain.domain.InspectionTask;
import com.yanfan.maintain.domain.ReleaseTask;
import com.yanfan.maintain.domain.model.TaskBody;
import com.yanfan.maintain.mapper.*;
import com.yanfan.maintain.service.InspectionService;
import com.yanfan.maintain.service.MaintenancePlanService;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

import static com.yanfan.common.utils.SecurityUtils.getLoginUser;
import static com.yanfan.common.utils.SecurityUtils.getUsername;

/**
 * 设备保养计划表(MaintenancePlan)表服务实现类
 *
 * @author makejava
 * @since 2023-03-09 15:02:16
 */
@Service("maintenancePlanService")
@Transactional(rollbackFor = Exception.class)
public class MaintenancePlanServiceImpl implements MaintenancePlanService {
    @Resource
    private MaintenancePlanDao maintenancePlanDao;
    @Resource
    private MaintenanceDeviceDao maintenanceDeviceDao;
    /**
     * 任务相关dao
     */
    @Resource
    private MaintainTasksDao maintainTasksDao;
    @Resource
    private ImageUrlDao imageUrlDao;
    /**
     * 任务图形数据接口
     */
    @Autowired
    private MaintainGraphTable maintainGraphTable;
    @Resource
    private InspectionService inspectionService;
    @Resource
    private EquipmentRepairServiceImpl equipmentRepairService;

    @Resource
    private IGroupService groupService;
    @Resource
    private IProductService productService;
    @Resource
    private DeviceDetailMapper deviceDetailMapper;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private IThingsModelService thingsModelService;
    @Resource
    private IThingModelCache thingModelCache;
    @Autowired
    private MaintainTasksItemsMapper maintainTasksItemsMapper;

    /**
     * 返回指定开始日期 -结束日期的   中间日期
     *
     * @param dBegin
     * @param dEnd
     * @return
     */
    public static Map<String, Long> findEveryDay(Date dBegin, Date dEnd) {
        // 创建一个放所有日期的集合
        Map<String, Long> res = new HashMap<>();
        // 创建时间解析对象规定解析格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        // 将格式化后的第一天添加进集合
        res.put(sdf.format(dBegin), 0L);
        // 使用本地的时区和区域获取日历
        Calendar calBegin = Calendar.getInstance();
        // 传入起始时间将此日历设置为起始日历
        calBegin.setTime(dBegin);
        // 判断结束日期前一天是否在起始日历的日期之后
        while (dEnd.after(calBegin.getTime())) {
            // 根据日历的规则:月份中的每一天，为起始日历加一天
            calBegin.add(Calendar.DAY_OF_MONTH, 1);
            // 得到的每一天就添加进集合
            res.put(sdf.format(calBegin.getTime()), 0L);
            // 如果当前的起始日历超过结束日期后,就结束循环
        }
        return res;
    }

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public MaintenancePlan queryById(Long id) {
        MaintenancePlan maintenancePlan = maintenancePlanDao.queryById(id);
        if (maintenancePlan != null) {
            maintenancePlan.setMaintainDevices(maintenanceDeviceDao.queryDeviceAndPartsByPlanId(id));
        }
        return maintenancePlan;
    }

    /**
     * 分页查询
     *
     * @param maintenancePlan 筛选条件
     * @return 查询结果
     */
    @Override
    public List<MaintenancePlan> queryByPage(MaintenancePlan maintenancePlan) {
        SysUser user = getLoginUser().getUser();
        if (!user.isAdmin()) {
            maintenancePlan.setUserId(user.getUserId());
        }
        PageHelper.startPage(maintenancePlan.getPageNum(), maintenancePlan.getPageSize());
        return this.maintenancePlanDao.queryAll(maintenancePlan);
    }

    /**
     * 新增数据
     *
     * @param maintenancePlan 实例对象
     * @return 实例对象
     */
    @Override
    public MaintenancePlan insert(MaintenancePlan maintenancePlan) {
        // 参数验证
        verifyParam(maintenancePlan);
        // 自动生成序列号 todo
        // 1. 新增计划
        this.maintenancePlanDao.insert(maintenancePlan);
        // 批量新增 设备
        maintenanceDeviceDao.insertBatch(maintenancePlan.getMaintainDevices(), maintenancePlan.getId());
        // 判断有没有设备零件
        ArrayList<MaintenanceDeviceParts> maintenanceDeviceParts = new ArrayList<>(); // 存放设备id 容器
        maintenancePlan.setItemNum(packDeviceParts(maintenancePlan, maintenanceDeviceParts));
        // 设备零件不为空 新增数据
        if (maintenanceDeviceParts.size() > 0) {
            maintenanceDeviceDao.insertDevicePartsBatch(maintenanceDeviceParts);
        }
        // 生成任务
        taskAdd(planToTask(maintenancePlan));
        // 更新 项目数 和下次执行时间
        maintenancePlan.setNextDate(getNextPeriod(maintenancePlan.getMaintainPeriod(), maintenancePlan.getMaintainTime()));
        maintenancePlan.setLastDate(getNextPeriod(maintenancePlan.getMaintainPeriod(), maintenancePlan.getMaintainTimeEnd()));
        maintenancePlanDao.update(maintenancePlan);
        return maintenancePlan;
    }

    private MaintainTasks planToTask(MaintenancePlan plan) {
        MaintainTasks maintainTasks = new MaintainTasks();
        maintainTasks.setTaskNumber(generateTaskNo(3)); // 任务编号
        maintainTasks.setTaskName(plan.getMaintainName() + "所属任务"); // 任务编号
        maintainTasks.setStartTime(plan.getMaintainTime());// 保养开始时间  下个周期
        maintainTasks.setEndTime(plan.getMaintainTimeEnd());// 保养开始时间  下个周期
        maintainTasks.setItemNum(Math.toIntExact(plan.getItemNum()));// 保养项数
        maintainTasks.setStaffId(plan.getMaintainPerson()); // 员工id
        maintainTasks.setStatus(Math.toIntExact(WorkOrderStatus.SUBMITTED.getCode())); // 状态
        maintainTasks.setPlanId(plan.getId()); // 计划Id
        maintainTasks.setPeriod(plan.getMaintainPeriod());
        maintainTasks.setOrderNumber(plan.getOrderNumber());
        maintainTasks.setOrderId(plan.getOrderId());
        maintainTasks.setOrderTypeId(plan.getOrderType());
        maintainTasks.setTaskTypeId(1); // 定时任务
        maintainTasks.setCreateUserName(plan.getCreateBy()); // 定时任务
        maintainTasks.setCreateUserId(plan.getCreatedId()); // 定时任务
        return maintainTasks;
    }

    /**
     * 周期
     *
     * @param period
     * @param date
     * @return
     */
    private Date getNextPeriod(Integer period, Date date) {
        if (DeviceManageEnums.PlanPeriod.HOURLY.getCode().equals(period)) {
            return DateUtils.nextTomorrow(date);
        } else if (DeviceManageEnums.PlanPeriod.WEEKLY.getCode().equals(period)) {
            return DateUtils.nextWeak(date);
        } else if (DeviceManageEnums.PlanPeriod.DAILY.getCode().equals(period)) {
            return DateUtils.nextMonth(date);
        }
        return date;
    }

    private Long packDeviceParts(MaintenancePlan maintenancePlan, ArrayList<MaintenanceDeviceParts> maintenanceDeviceParts) {
        // 维修项目数
        Long itemNum = 0L;
        List<MaintenanceDevice> maintenanceDevices = maintenancePlan.getMaintainDevices();
        // 循环设备判断有没有零件
        for (MaintenanceDevice maintenanceDevice : maintenanceDevices) {
            List<MaintenanceDeviceParts> deviceParts = maintenanceDevice.getMaintainDeviceParts();
            if (!CollectionUtils.isEmpty(deviceParts)) {
                for (MaintenanceDeviceParts devicePart : deviceParts) {
                    devicePart.setMaintainDeviceId(maintenanceDevice.getId());// 设备-维修计划plan  关联关系表id
                    devicePart.setPlanId(maintenancePlan.getId()); // 计划id
                    maintenanceDeviceParts.add(devicePart);// 添加数据
                    itemNum++;
                }
            } else {
                itemNum++;
            }
        }

        return itemNum;
    }

    /**
     * 修改数据
     *
     * @param maintenancePlan 实例对象
     * @return 实例对象
     */
    @Override
    public MaintenancePlan update(MaintenancePlan maintenancePlan) {
        // 参数验证
        verifyParam(maintenancePlan);
        /**
         * 删除之前的关联关系 ，和设备零件信息
         */
        maintenanceDeviceDao.deleteByPlanId(maintenancePlan.getId());
        maintenanceDeviceDao.deleteDevicePartsByPlanId(maintenancePlan.getId()); // 删除零件

        /**
         * 新增设备信息
         */

        // 重新新增关联关系
        maintenanceDeviceDao.insertBatch(maintenancePlan.getMaintainDevices(), maintenancePlan.getId());
        /**
         * 新增零件
         */
        // 判断有没有设备零件
        ArrayList<MaintenanceDeviceParts> maintenanceDeviceParts = new ArrayList<>(); // 存放设备id 容器
        maintenancePlan.setItemNum(packDeviceParts(maintenancePlan, maintenanceDeviceParts)); // 保修计划 维修项目数
        // 设备零件不为空 新增数据
        if (maintenanceDeviceParts.size() > 0) {
            maintenanceDeviceDao.insertDevicePartsBatch(maintenanceDeviceParts);
        }
        // 更新计划列表
        this.maintenancePlanDao.update(maintenancePlan);
        return this.queryById(maintenancePlan.getId());
    }

    private void verifyParam(MaintenancePlan maintenancePlan) {
        // 判断设备列表是否为空
        if (CollectionUtils.isEmpty(maintenancePlan.getMaintainDevices())) {
            throw new BaseException("设备列表不为能为空");
        }
        for (MaintenanceDevice device : maintenancePlan.getMaintainDevices()) {
         /*   if (StringUtils.isEmpty(device.getDeviceName())) {
                throw new BaseException("deviceName 设备名称不能为空  ");
            }*/
            if (device.getDeviceId() == null) {
                throw new BaseException("deviceId  设备ID不能为空  ");
            }
/*            if (StringUtils.isEmpty(device.getProductName())) {
                throw new BaseException("productName 产品名称不能为空  ");
            }
            if (device.getProductId() ==null) {
                throw new BaseException("productId  产品类型ID不能为空  ");
            }*/
        }
        if (!DeviceManageEnums.PlanPeriod.thisPeriodIsExist(maintenancePlan.getMaintainPeriod())) {
            // 时->每天的指定的那个小时 ; 日 ： 每月的那个时间 周： 星期几
            throw new BaseException("计划周期 只能为  时-1，日-2 ，周-3  ");
        }
        if (maintenancePlan.getMaintainTime() == null) {
            // 时->每天的指定的那个小时 ; 日 ： 每月的那个时间 周： 星期几
            throw new BaseException("计划指定开始时间不能为空  maintainTime");
        }
        // 设置 下一次执行时间
        if (DeviceManageEnums.PlanPeriod.HOURLY.getCode().equals(maintenancePlan.getMaintainPeriod())) {
            // if (maintenancePlan.getMaintainTime().before(DateUtil.getTomorrow())) {
            maintenancePlan.setNextDate(DateUtils.nextTomorrow(maintenancePlan.getMaintainTime()));
        } else if (DeviceManageEnums.PlanPeriod.WEEKLY.getCode().equals(maintenancePlan.getMaintainPeriod())) {
            maintenancePlan.setNextDate(DateUtils.nextWeak(maintenancePlan.getMaintainTime()));
        } else if (DeviceManageEnums.PlanPeriod.DAILY.getCode().equals(maintenancePlan.getMaintainPeriod())) {
            maintenancePlan.setNextDate(DateUtils.nextMonth(maintenancePlan.getMaintainTime()));
        }
        maintenancePlan.setCreateTime(new Date());
        SysUser user = getLoginUser().getUser();
        maintenancePlan.setCreatedId(user.getUserId());
        maintenancePlan.setCreateBy(user.getNickName());
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Long id) {
        /**
         * 删除之前的关联关系 ，和设备零件信息
         */
        maintenanceDeviceDao.deleteByPlanId(id);// 删除设备
        maintenanceDeviceDao.deleteDevicePartsByPlanId(id); // 删除零件
        return this.maintenancePlanDao.deleteById(id) > 0;
    }

    /*****
     * ---------------------------------------------------------------------------------- 任务相关信息接口    ----------------------------------------------------------------------------------
     */

    /**
     * 下拉框查询
     *
     * @param baseDictEntity
     * @return
     */
    @Override
    public List<BaseOrderEntity> comboBoxLinkage(BaseDictEntity baseDictEntity) {
        SysUser user = getLoginUser().getUser();
        if (!user.isAdmin()) {
            baseDictEntity.setUserId(user.getUserId());
        }
        if (baseDictEntity.getType() == null) {
            throw new BaseException("type 能为空（1： 楼栋   2： 车间  3：设备）");
        }
        if (user.isAdmin()) {
            return maintenancePlanDao.comboBoxLinkage(baseDictEntity);
        }
        baseDictEntity.setDeptId(SecurityUtils.getDeptId().intValue());
        return maintenancePlanDao.comboBoxLinkageByAdmin(baseDictEntity);
    }

    /**
     * 任务列表
     *
     * @return
     */
    @Override
    public List<MaintainTasks> taskList(MaintainTasks tasks) {
        return maintainTasksDao.queryList(tasks);
    }

    /**
     * 任务列表
     *
     * @param maintenancePlan WorkOrderStatus 枚举已完成
     * @return
     */
    @Override
    public List<MaintainTasks> taskListByPlan(MaintenancePlan maintenancePlan) {
        if (maintenancePlan.getId() == null) {
            throw new BaseException("计划id 不能为空");
        }
        MaintainTasks maintainTasks = new MaintainTasks();
        maintainTasks.setPlanId(maintenancePlan.getId());
        PageHelper.startPage(maintenancePlan.getPageNum(), maintenancePlan.getPageSize());
        return maintainTasksDao.queryList(maintainTasks);
    }

    /**
     * 保养计划顶部接口
     *
     * @param maintainTopRequest
     * @return
     */
    @Override
    public Map maintainTop(MaintainTopRequest maintainTopRequest) {
        return maintainGraphTable.maintainGraphInfo(maintainTopRequest);
    }

    /**
     * 任务分页相关接口
     *
     * @param maintainTasks
     * @return
     */
    @Override
    public List<MaintainTasks> queryTaskByPage(MaintainTasks maintainTasks) {
        SysUser user = getLoginUser().getUser();
        if (!user.isAdmin()) {
            maintainTasks.setUserId(user.getUserId());
        }
        PageHelper.startPage(maintainTasks.getPageNum(), maintainTasks.getPageSize());
        return maintainTasksDao.queryTaskByPage(maintainTasks);
    }

    /**
     * 查询任务详情
     *
     * @param id
     * @return
     */

    @Override
    public MaintainTasks queryTaskById(Long id) {
        MaintainTasks maintainTasks = maintainTasksDao.queryById(id);
        if (maintainTasks != null) {
            // maintainTasks.setTasksDevices(maintainTasksDao.queryTaskDevicePartsByPlanId(id));
            maintainTasks.setDevices(maintainTasksDao.queryDeviceByPlanId(id));
            ImageUrl imageUrl = new ImageUrl();
            imageUrl.setType(DeviceManageEnums.ImageType.DEVICE_MAINTENANCE.getCode());
            imageUrl.setOrderId(id);
            imageUrl.setBusType(1);
            maintainTasks.setImageUrlList(imageUrlDao.queryAll(imageUrl));
        }
        return maintainTasks;
    }

    /**
     * 通过任务ID 删除任务 以及任务相关联的设备、零件信息
     *
     * @param id
     * @return 删除任务的个数
     */
    @Override
    public int deleteTaskById(Long id) {
        // 删除任务
        int i = maintainTasksDao.deleteById(id);
        if (i <= 0) {
            return i;
        }
        // 删除任务相关联设备
        maintainTasksDao.deleteTaskDeviceByTaskId(id);
        maintainTasksDao.deleteTaskPartsByTaskId(id);
        // 删除任务相关联 设备零件
        return i;
    }

    @Override
    @Transactional
    public int deleteTaskByIds(Long[] ids) {
        if (ids != null && ids.length > 0) {
            for (Long id : ids) {
                deleteTaskById(id);
            }
            return 1;
        }
        return 0;
    }

    /**
     * 任务新增
     *
     * @param maintainTasks
     * @return
     */

    @Override
    public MaintainTasks taskAdd(MaintainTasks maintainTasks) {
        /**
         * 参数验证, 1. 验证设备列表是否为空 2. 验证巡检单号是否存在
         */
        verifyParamTask(maintainTasks);

        if (Objects.isNull(maintainTasks.getStatus())) {
            maintainTasks.setStatus(Math.toIntExact(WorkOrderStatus.SUBMITTED.getCode()));
        }
        maintainTasks.setFlawNumber(0);
        SysUser user = getLoginUser().getUser();
        maintainTasks.setCreateUserId(user.getUserId());
        maintainTasks.setCreateUserName(user.getNickName());
        maintainTasks.setCreateDate(new Date());

        // 自动生成序列号 todo
        // 1. 新增任务
        maintainTasksDao.insert(maintainTasks);
        // 2. 批量新增 设备 FIXME lsy
        maintainTasksDao.insertBatchDevice1(maintainTasks.getDevices(), maintainTasks.getId());

        if (ObjUtil.isNotNull(maintainTasks.getTasksItems())) {
            for (MaintainTasksItems tasksItem : maintainTasks.getTasksItems()) {
                tasksItem.setMaintainTaskId(maintainTasks.getId());
            }
            maintainTasksItemsMapper.insertBatchItems(maintainTasks.getTasksItems());
        }

        // 3. 判断有没有设备零件  有，就新增零件
        List<MaintainTasksDeviceParts> tasksDevicePartsContainer = new ArrayList<>(); // // 存设备零件的 容器
        // maintainTasks.setItemNum(packTaskDeviceParts(maintainTasks, tasksDevicePartsContainer));
        // 设备零件不为空 新增数据
        if (tasksDevicePartsContainer.size() > 0) {
            maintainTasksDao.insertBatchParts(tasksDevicePartsContainer);
        }
        // 更新 项目数
        maintainTasksDao.update(maintainTasks);

        if (Objects.nonNull(maintainTasks.getImageUrlList())) {
            ImageUrl imgs = new ImageUrl();
            imgs.setOrderId(maintainTasks.getId());
            imgs.setType(DeviceManageEnums.ImageType.DEVICE_MAINTENANCE.getCode());
            imgs.setBusType(1);

            imageUrlDao.deleteByOrderIdType(imgs);
            for (ImageUrl imageUrl : maintainTasks.getImageUrlList()) {
                if (!StrUtil.isEmpty(imageUrl.getImgUrl())) {
                    imageUrl.setOrderId(maintainTasks.getId());
                    imageUrl.setType(DeviceManageEnums.ImageType.DEVICE_MAINTENANCE.getCode());
                    imageUrl.setBusType(1);
                }

            }
            if (!CollectionUtils.isEmpty(maintainTasks.getImageUrlList())) {
                imageUrlDao.insertBatch(maintainTasks.getImageUrlList());
            }
        }
        return maintainTasks;
    }

    /**
     * 参数验证
     *
     * @param maintainTasks
     */
    private void verifyParamTask(MaintainTasks maintainTasks) {
        // 判断设备列表是否为空
        if (CollectionUtils.isEmpty(maintainTasks.getDevices())) {
            throw new BaseException("设备列表能为空  （tasksDevices 列表不能为空）");
        }
        for (DeviceDetail device : maintainTasks.getDevices()) {
            if (device.getDeviceId() == null) {
                throw new BaseException("deviceId  设备ID不能为空  ");
            }
           /* if (device.getProductId() ==null) {
                throw new BaseException("productId  产品类型ID不能为空  ");
            }*/
        }
    }

    /**
     * 任务修改
     *
     * @param maintainTasks
     * @return
     */

    @Override
    public MaintainTasks taskEdit(MaintainTasks maintainTasks) {
        /**
         * 参数验证, 1. 验证设备列表是否为空 2. 验证巡检单号是否存在
         */
        verifyParamTask(maintainTasks);
        /**
         * 删除之前的关联关系 ，和设备零件信息
         */
        maintainTasksDao.deleteTaskDeviceByTaskId(maintainTasks.getId());
        maintainTasksDao.deleteTaskPartsByTaskId(maintainTasks.getId()); // 删除零件
        // 2. 批量新增 设备
        maintainTasksDao.insertBatchDevice1(maintainTasks.getDevices(), maintainTasks.getId());
        // 3. 判断有没有设备零件  有，就新增零件
        List<MaintainTasksDeviceParts> tasksDevicePartsContainer = new ArrayList<>(); // // 存设备零件的 容器
        // maintainTasks.setItemNum(packTaskDeviceParts(maintainTasks, tasksDevicePartsContainer));
        // 设备零件不为空 新增数据
        if (tasksDevicePartsContainer.size() > 0) {
            maintainTasksDao.insertBatchParts(tasksDevicePartsContainer);
        }
        // 更新 项目数
        maintainTasksDao.update(maintainTasks);

        if (Objects.nonNull(maintainTasks.getImageUrlList())) {
            ImageUrl imgs = new ImageUrl();
            imgs.setOrderId(maintainTasks.getId());
            imgs.setType(DeviceManageEnums.ImageType.DEVICE_MAINTENANCE.getCode());
            imgs.setBusType(1);
            imageUrlDao.deleteByOrderIdType(imgs);
            for (ImageUrl imageUrl : maintainTasks.getImageUrlList()) {
                if (!StrUtil.isEmpty(imageUrl.getImgUrl())) {
                    imageUrl.setOrderId(maintainTasks.getId());
                    imageUrl.setType(DeviceManageEnums.ImageType.DEVICE_MAINTENANCE.getCode());
                    imageUrl.setBusType(1);
                }

            }
            if (!CollectionUtils.isEmpty(maintainTasks.getImageUrlList())) {
                imageUrlDao.insertBatch(maintainTasks.getImageUrlList());
            }
        }

        return queryTaskById(maintainTasks.getId());
    }

    @Override
    public Map<String, List<MaintainTasks>> showPlansByMonth(String yearMonth) {
        String[] parts = yearMonth.split("-");
        int year = Integer.parseInt(parts[0]);
        int month = Integer.parseInt(parts[1]);
        // 存放所有任务的容器
        Map<String, List<MaintainTasks>> tasks = new HashMap<>();
        Long userId = null;
        SysUser user = getLoginUser().getUser();
        if (!user.isAdmin()) {
            userId = user.getUserId();
        }
        // 查看在 year month 时创建的计划 或 之前 （将来的计划 不能影响之前的任务）
        List<MaintainTasks> maintainTasks = maintainTasksDao.queryAllBeforeDate(DateUtils.getFirstMonthDay(year, month), DateUtils.getLastMonthDay(year, month), userId);
        if (CollectionUtils.isEmpty(maintainTasks)) {
            return tasks;
        }
        for (MaintainTasks maintainTask : maintainTasks) {
            String key = DateUtils.getYearMonthDateStr(maintainTask.getStartTime());
            if (tasks.containsKey(key)) {
                tasks.get(key).add(maintainTask);
            } else {
                ArrayList<MaintainTasks> list = new ArrayList<>();
                list.add(maintainTask);
                tasks.put(key, list);
            }
        }
        return tasks;
    }

    @Override
    public List<BaseOrderEntity> planPeriodList() {
        List<BaseOrderEntity> repList = new ArrayList<>();
        for (DeviceManageEnums.PlanPeriod item : DeviceManageEnums.PlanPeriod.values()) {
            BaseOrderEntity baseOrderEntity = new BaseOrderEntity();
            baseOrderEntity.setName(item.getDesc());
            baseOrderEntity.setId(Long.valueOf(item.getCode()));
            repList.add(baseOrderEntity);
        }
        return repList;
    }

    @Override
    public List<BaseOrderEntity> planTypeList() {
        List<BaseOrderEntity> repList = new ArrayList<>();
        for (DeviceManageEnums.PlanType item : DeviceManageEnums.PlanType.values()) {
            BaseOrderEntity baseOrderEntity = new BaseOrderEntity();
            baseOrderEntity.setName(item.getDesc());
            baseOrderEntity.setId(Long.valueOf(item.getCode()));
            repList.add(baseOrderEntity);
        }
        return repList;
    }

    @Override
    public Map operationCase() {
        /**
         * 初始化
         **/
        Map<String, Map<String, Long>> resMap = new HashMap();
        resMap.put("inspection", currentMonthDayMap()); // 巡检
        resMap.put("upkeep", currentMonthDayMap()); // 保养
        resMap.put("repair", currentMonthDayMap());// 维修
        // 初始化
        List<OperationCase> list = maintainTasksDao.queryOpertainCase();
        if (CollectionUtils.isEmpty(list)) {
            return resMap;
        }
        for (OperationCase operationCase : list) {
            if (resMap.get(operationCase.getType()) != null && resMap
                    .get(operationCase.getType())
                    .get(operationCase.getDate()) != null) {
                resMap.get(operationCase.getType()).put(operationCase.getDate(), operationCase.getNum());
            }
        }
        return resMap;
    }

    public Map currentMonthDayMap() {
        Map<String, Long> dateMap = new LinkedHashMap<>();
        Calendar cal = Calendar.getInstance();
        // 获取当前月份的天数
        int daysInMonth = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        SimpleDateFormat sdf = new SimpleDateFormat("MM-dd");
        // 打印当前月份的日期
        for (int day = 1; day <= daysInMonth; day++) {
            cal.set(Calendar.DAY_OF_MONTH, day);
            dateMap.put(sdf.format(cal.getTime()), 0L);
        }
        return dateMap;
    }

    @Override
    public Map operationCaseNew(DeviceChartRequest request) {
        if (request.getDateType() == null) {
            throw new BaseException("dateType 日期类型不能为空");
        }
        initializedParam(request);
        /**
         * 初始化
         **/
        Map<String, Map<String, Long>> resMap = new HashMap();
        resMap.put("inspection", currentDateMap(request)); // 巡检
        resMap.put("upkeep", currentDateMap(request)); // 保养
        resMap.put("repair", currentDateMap(request));// 维修

        SysUser user = getLoginUser().getUser();
        if (!user.isAdmin()) {
            request.setUserId(user.getUserId());
        }
        // 因为sql太复杂了， 为了简化sql
        if (StrUtil.isEmpty(request.getDeviceName())) {
            request.setDeviceName(null);
        }
        List<OperationCase> list = maintainTasksDao.operationCaseNew(request);
        if (CollectionUtils.isEmpty(list)) {
            return resMap;
        }
        for (OperationCase operationCase : list) {
            if (resMap.get(operationCase.getType()) != null && resMap
                    .get(operationCase.getType())
                    .get(operationCase.getDate()) != null) {
                resMap.get(operationCase.getType()).put(operationCase.getDate(), operationCase.getNum());
            }
        }
        return resMap;
    }

    @Override
    public Map deviceDevOps(DeviceChartRequest request) {
        if (request.getDeviceId() == null) {
            throw new BaseException("deviceId 设备Id不能为空");
        }
        if (request.getDateType() == null) {
            throw new BaseException("dateType 日期类型不能为空");
        }
        initializedParam(request);
        Map<String, Map<String, Long>> resMap = new HashMap();
        resMap.put("3", currentDateMap(request)); // 事件上报
        resMap.put("5", currentDateMap(request)); // 设备上线
        resMap.put("2", currentDateMap(request));// 调用功能
        List<OperationCase> list = maintainTasksDao.deviceDevOps(request);
        if (CollectionUtils.isEmpty(list)) {
            return resMap;
        }
        for (OperationCase operationCase : list) {
            if (resMap.get(operationCase.getType()) != null && resMap
                    .get(operationCase.getType())
                    .get(operationCase.getDate()) != null) {
                resMap.get(operationCase.getType()).put(operationCase.getDate(), operationCase.getNum());
            }
        }
        return resMap;
    }

    /**
     * 设备运维-任务管理
     *
     * @param request
     * @return
     */
    @Override
    public List<DevOpsTask> devOpsTask(DevOpsTask request) {
        SysUser user = getLoginUser().getUser();
        if (!user.isAdmin()) {
            request.setCurrentUserId(user.getUserId());
        }
        if (!(request.getPageSize() == 0 && request.getPageSize() == 0)) {
            PageHelper.startPage(request.getPageNum(), request.getPageSize());
        }
        return maintainTasksDao.devOpsTaskList(request);
    }

    /**
     * 设备运维任务 分析  （设备运维任务管理 顶部接口）
     *
     * @param request
     * @return
     */
    @Override
    public DevOpsAnalyse devOpsAnalyse(DeviceChartRequest request) {
        initializedParam(request);
        SysUser user = getLoginUser().getUser();
        if (!user.isAdmin()) {
            request.setUserId(user.getUserId());
        }
        List<OperationCase> list = maintainTasksDao.devOpsAnalyse(request);
        DevOpsAnalyse devOpsAnalyse = new DevOpsAnalyse();
        if (CollectionUtils.isEmpty(list)) {
            return devOpsAnalyse;
        }
        for (OperationCase operationCase : list) {
            if (BatchesStatus.PENDING.getCode().equals(operationCase.getState())) {
                devOpsAnalyse.setUnfinishedCount((int) (devOpsAnalyse.getUnfinishedCount() + operationCase.getNum()));
                if ("inspection".equals(operationCase.getType())) {
                    devOpsAnalyse.setInspectionUnfinished((int) (devOpsAnalyse.getInspectionUnfinished() + operationCase.getNum()));
                } else if ("upkeep".equals(operationCase.getType())) {
                    devOpsAnalyse.setUpkeepUnfinished((int) (devOpsAnalyse.getUpkeepUnfinished() + operationCase.getNum()));
                } else if ("repair".equals(operationCase.getType())) {
                    devOpsAnalyse.setRepairUnfinished((int) (devOpsAnalyse.getRepairUnfinished() + operationCase.getNum()));
                }
            } else if (BatchesStatus.IN_PRODUCTION.getCode().equals(operationCase.getState())) {
                devOpsAnalyse.setUnderWayCount((int) (devOpsAnalyse.getUnderWayCount() + operationCase.getNum()));
                if ("inspection".equals(operationCase.getType())) {
                    devOpsAnalyse.setInspectionUnderWay((int) (devOpsAnalyse.getInspectionUnderWay() + operationCase.getNum()));
                } else if ("upkeep".equals(operationCase.getType())) {
                    devOpsAnalyse.setUpkeepUnderWay((int) (devOpsAnalyse.getUpkeepUnderWay() + operationCase.getNum()));
                } else if ("repair".equals(operationCase.getType())) {
                    devOpsAnalyse.setRepairUnderWay((int) (devOpsAnalyse.getRepairUnderWay() + operationCase.getNum()));
                }
            } else if (BatchesStatus.FINISHED.getCode().equals(operationCase.getState())) {
                devOpsAnalyse.setFinishedCount((int) (devOpsAnalyse.getFinishedCount() + operationCase.getNum()));
                if ("inspection".equals(operationCase.getType())) {
                    devOpsAnalyse.setInspectionFinished((int) (devOpsAnalyse.getInspectionFinished() + operationCase.getNum()));
                } else if ("upkeep".equals(operationCase.getType())) {
                    devOpsAnalyse.setUpkeepFinished((int) (devOpsAnalyse.getUpkeepFinished() + operationCase.getNum()));
                } else if ("repair".equals(operationCase.getType())) {
                    devOpsAnalyse.setRepairFinished((int) (devOpsAnalyse.getRepairFinished() + operationCase.getNum()));
                }
            }
        }
        return devOpsAnalyse;
    }

    @Override
    public List<DevOpsTask> devOpsTaskRecord(DevOpsTask request) {
        SysUser user = getLoginUser().getUser();
        if (!user.isAdmin()) {
            request.setCurrentUserId(user.getUserId());
        }
        if (!(request.getPageSize() == 0 && request.getPageSize() == 0)) {
            PageHelper.startPage(request.getPageNum(), request.getPageSize());
        }
        return maintainTasksDao.devOpsTaskRecord(request);
    }

    /**
     * 任务完成
     *
     * @param request
     */
    @Override
    public void devOpsTaskFinish(DevOpsTask request) {
        if (request.getTaskType() == null) {
            throw new BaseException(" taskType 任务类型不能为空");
        }
        if (request.getId() == null) {
            throw new BaseException("任务ID不能为空");
        }
        maintainTasksDao.insertProgress(getTaskProgress(request.getId(), request.getTaskType(), "完成了该任务"));

        maintainTasksDao.devOpsTaskFinish(request);
    }

    /**
     * 任务开始
     *
     * @param request
     */
    @Override
    public void devOpsTaskStart(DevOpsTask request) {
        if (request.getTaskType() == null) {
            throw new BaseException(" taskType 任务类型不能为空");
        }
        if (request.getId() == null) {
            throw new BaseException("任务ID不能为空");
        }
        maintainTasksDao.insertProgress(getTaskProgress(request.getId(), request.getTaskType(), "开始了该任务"));

        maintainTasksDao.devOpsTaskStart(request);
    }

    /**
     * 处理意见
     *
     * @param request
     */
    @Override
    public void devOpsTaskHandling(DevOpsTask request) {
        if (StrUtil.isEmpty(request.getHandlingOpinion())) {
            throw new BaseException("handlingOpinion 处理意见不能为空");
        }
        if (request.getTaskType() == null) {
            throw new BaseException("任务类型不能为空");
        }
        if (request.getId() == null) {
            throw new BaseException("任务ID不能为空");
        }
        maintainTasksDao.insertProgress(getTaskProgress(request.getId(), request.getTaskType(), "添加了处理建议（" + request.getHandlingOpinion() + ")"));
        // 处理意见
        maintainTasksDao.devOpsTaskHandling(request);
        if (CollectionUtils.isEmpty(request.getImageUrlList())) {
            return;
        }
        for (ImageUrl imageUrl : request.getImageUrlList()) {
            if (!StrUtil.isEmpty(imageUrl.getImgUrl())) {
//                imageUrl.setImgUrl(imageUrl.getImgUrl().replace("/profile",""));
                imageUrl.setOrderId(request.getId());
                imageUrl.setType(request.getTaskType());
            }

        }
        imageUrlDao.insertBatch(request.getImageUrlList());
    }

    /**
     * 发布任务
     *
     * @param request
     */
    @Override
    public void releaseTask(ReleaseTask request) {
        // 巡检 关联  路线名、路线所属设备数量
        if (DeviceManageEnums.ImageType.DEVICE_MAINTENANCE.getCode().equals(request.getTaskType())) {
            MaintainTasks tasks = releaseTaskToMaintain(request);
            taskAdd(tasks);
        } else if (DeviceManageEnums.ImageType.DEVICE_INSPECTION.getCode().equals(request.getTaskType())) {
            // 巡检
            InspectionTask inspectionTask = releaseTaskToInspectionTask(request);
            inspectionService.addInspectionTask(inspectionTask);
        } else if (DeviceManageEnums.ImageType.DEVICE_REPAIR.getCode().equals(request.getTaskType())) {
            // 维修
            EquipmentRepair equipmentRepair = releaseTaskToEquipmentRepair(request);
            equipmentRepairService.insert(equipmentRepair);
        }
    }

    @Override
    public ReleaseTask devOpsTaskDetails(ReleaseTask request) {
        if (request.getTaskType() == null) {
            throw new BaseException("任务类型不能为空");
        }
        if (request.getId() == null) {
            throw new BaseException("任务ID不能为空");
        }
        ReleaseTask task = null;
        maintainTasksDao.insertProgress(getTaskProgress(request.getId(), request.getTaskType(), "查看了该任务"));
        // 保养
        if (DeviceManageEnums.ImageType.DEVICE_MAINTENANCE.getCode().equals(request.getTaskType())) {
            MaintainTasks maintainTasks = queryTaskById(request.getId());
            task = maintainToReleaseTask(maintainTasks);
            task.setMaintain(maintainTasks);
        } else if (DeviceManageEnums.ImageType.DEVICE_INSPECTION.getCode().equals(request.getTaskType())) {
            // 巡检
            task = maintainTasksDao.inspectionDetail(request.getId());
            InspectionTask inspectionTask = inspectionService.selectInspectionTaskById(request.getId());
            // InspectionRoute inspectionRoute = inspectionService.selectInspectionRoutesByRoutesId(task.getRoutesId());
            List<DeviceDetail> devices = inspectionService.selectDeviceByRoutesId(task.getRoutesId());
            task.setDevices(devices);

            ImageUrl imageUrl = new ImageUrl();
            imageUrl.setType(request.getTaskType());
            imageUrl.setOrderId(request.getId());
            imageUrl.setBusType(1);
            task.setImageUrlList(imageUrlDao.queryAll(imageUrl));
            // task.setInspectionRoute(inspectionRoute);
            task.setInspection(inspectionTask);
            task.setType(inspectionTask.getType());
        } else if (DeviceManageEnums.ImageType.DEVICE_REPAIR.getCode().equals(request.getTaskType())) {
            // 维修
            EquipmentRepair repair = equipmentRepairService.queryById(request.getId());
            if (repair == null) {
                return task;
            }
            task = equipmentRepairToReleaseTask(repair);
        }
        SysUser user = getLoginUser().getUser();
        if (user.isAdmin() || task.getPrincipal() != SecurityUtils.getUserId()) {
            List<TaskProgress> taskProgresses = maintainTasksDao.queryProgressByTypeId(request);
            if (CollectionUtils.isEmpty(taskProgresses)) {
                taskProgresses = new ArrayList<>();
            }
            task.setTaskProgresses(taskProgresses);
        }

        task.setId(request.getId());
        return task;
    }

    @Override
    public ReleaseTask devOpsTaskModify(ReleaseTask request) {
        // 任务管理修改
        if (request.getId() == null) {
            throw new BaseException("任务修改 id不能为空");
        }
        // 巡检 关联  路线名、路线所属设备数量
        if (DeviceManageEnums.ImageType.DEVICE_MAINTENANCE.getCode().equals(request.getTaskType())) {
            MaintainTasks tasks = releaseTaskToMaintain(request);
            tasks.setId(request.getId());
            taskEdit(tasks);
        } else if (DeviceManageEnums.ImageType.DEVICE_INSPECTION.getCode().equals(request.getTaskType())) {
            // 巡检
            InspectionTask inspectionTask = releaseTaskToInspectionTask(request);
            inspectionTask.setId(request.getId());
            inspectionService.updateInspectionTask(inspectionTask);
        } else if (DeviceManageEnums.ImageType.DEVICE_REPAIR.getCode().equals(request.getTaskType())) {
            // 维修
            EquipmentRepair equipmentRepair = releaseTaskToEquipmentRepair(request);
            equipmentRepair.setId(request.getId());
            equipmentRepairService.update(equipmentRepair);
        }
        maintainTasksDao.insertProgress(getTaskProgress(request.getId(), request.getTaskType(), "修改了该任务"));
        //添加日志
        if (request.getDevices().size() != 0) {
            addMaintainLogs("修改了维修设备信息", request.getDevices().get(0).getDeviceId());
            updatelifeCycle(request.getDevices().get(0).getDeviceId());
            addMaintainLogs("生命周期拆", request.getDevices().get(0).getDeviceId());
        }
        return devOpsTaskDetails(request);
    }

    @Override
    public Map<String, Integer> selectDeviceStatistic(DeviceChartRequest request) {
        Map resMap = new HashMap();
        resMap.put("deviceOnlineCount", 0);    // 在线
        resMap.put("deviceOffLineCount", 0);  // 离线
        resMap.put("deviceBreakdownCount", 0); // 故障
        resMap.put("deviceInactiveCount", 0);  // 未激活
        SysUser user = getLoginUser().getUser();
        if (!user.isAdmin()) {
            request.setUserId(user.getUserId());
        }
        List<BaseDictEntity> baseDictEntityList = maintainTasksDao.selectDeviceStatistic(request);
        if (CollectionUtils.isEmpty(baseDictEntityList)) {
            return resMap;
        }
        for (BaseDictEntity baseDictEntity : baseDictEntityList) {
            if (resMap.containsKey(baseDictEntity.getK())) {
                resMap.put(baseDictEntity.getK(), baseDictEntity.getType());
            }
        }
        return resMap;
    }

    /**
     * 生成记录  TaskProgress 对象
     *
     * @param
     * @param
     * @return
     */
    private TaskProgress getTaskProgress(Long taskId, Integer taskType, String detail) {
        TaskProgress taskProgress = new TaskProgress();
        taskProgress.setTaskId(taskId);
        taskProgress.setTaskType(taskType);
        SysUser user = getLoginUser().getUser();
        taskProgress.setOperatorId(user.getUserId());
        taskProgress.setOperatorName(user.getNickName());
        taskProgress.setOperationTime(new Date());
        taskProgress.initProgressContent(detail);
        return taskProgress;
    }

    /**
     * EquipmentRepair 实体 转 ReleaseTask 实体对象
     *
     * @param repair
     * @return
     */
    private ReleaseTask equipmentRepairToReleaseTask(EquipmentRepair repair) {
        ReleaseTask releaseTask = new ReleaseTask();
        releaseTask.setTaskName(repair.getRepairName());
        releaseTask.setContent(repair.getContent());
        releaseTask.setTaskBegin(repair.getBeginDate()); // 任务开始 时间
        releaseTask.setTaskEnd(repair.getEndDate()); // 任务结束 时间
        releaseTask.setPrincipal(repair.getRepairPerson());
        releaseTask.setPrincipalName(repair.getRepairPersonName());
        releaseTask.setCreator(repair.getCreateName());
        releaseTask.setCreateId(repair.getCreateId());
        releaseTask.setTaskNumber(repair.getRepairNumber());
        releaseTask.setTaskStatus(repair.getStatus());
        releaseTask.setTaskStatusName(repair.getStatusName());
        // 设备、产品相关
        // List<Device> devices = new ArrayList<>();
        // Device device = new Device();
        // device.setDeviceId(repair.getEquipmentId());
        // device.setDeviceName(repair.getEquipmentName());
        // device.setProductId(repair.getProductId());
        // device.setProductName(repair.getProductName());
        // devices.add(repair.getDevice());
        releaseTask.setDevices(Collections.singletonList(repair.getDevice()));
        releaseTask.setSparePartsList(repair.getSparePartsList());
        releaseTask.setTaskType(DeviceManageEnums.ImageType.DEVICE_REPAIR.getCode());
        releaseTask.setTaskTypeName("维修");
        releaseTask.setDeptId(repair.getDeptId());
        releaseTask.setDeptName(repair.getDeptName());
        releaseTask.setRepair(repair);
        releaseTask.setTaskDate(repair.getRepairDate());
        releaseTask.setRecommended(repair.getRecommended());

        return releaseTask;
    }

    /**
     * ReleaseTask 实体 转 EquipmentRepair 实体对象
     *
     * @param request
     * @return
     */
    private EquipmentRepair releaseTaskToEquipmentRepair(ReleaseTask request) {
        EquipmentRepair repair;
        if (Objects.isNull(request.getRepair())) {
            repair = new EquipmentRepair();
        } else {
            repair = request.getRepair();
        }
        if (StringUtils.isNotEmpty(request.getTaskNumber())) {
            repair.setRepairNumber(request.getTaskNumber());
        }

        if (StringUtils.isEmpty(repair.getRepairNumber())) {
            repair.setRepairNumber(generateTaskNo(DeviceManageEnums.ImageType.DEVICE_REPAIR.getCode()));
        }

        repair.setStatus(request.getTaskStatus());
        repair.setRepairName(request.getTaskName());
        repair.setContent(request.getContent());
        if (Objects.nonNull(request.getTaskBegin())) {
            repair.setBeginDate(request.getTaskBegin());
        }
        if (Objects.nonNull(request.getTaskEnd())) {
            repair.setEndDate(request.getTaskEnd());
        }
        SysUser user = getLoginUser().getUser(); // 当前登录人
        repair.setCreateId(user.getUserId()); // 创建人id
        repair.setCreateName(user.getNickName()); // 创建人名字
        if (CollectionUtils.isEmpty(request.getDevices())) {
            throw new BaseException("设备不能为空");
        }
        repair.setEquipmentId(request.getDevices().get(0).getDeviceId()); // 设备ID
        repair.setEquipmentName(request.getDevices().get(0).getDeviceName()); // 设备名称
        repair.setSparePartsList(request.getSparePartsList());
        repair.setImageUrlList(request.getImageUrlList());
        repair.setConfirmImages(request.getConfirmImages());
        repair.setRepairDate(request.getTaskDate());
        repair.setRecommended(request.getRecommended());
        return repair;
    }

    /**
     * ReleaseTask 实体 转 InspectionTask 实体对象
     *
     * @param request
     * @return
     */
    private InspectionTask releaseTaskToInspectionTask(ReleaseTask request) {
        InspectionTask inspectionTask = new InspectionTask();

        if (ObjUtil.isNotNull(request.getInspection())) {
            inspectionTask = request.getInspection();
        }

        // inspectionTask.setRoutesId(request.getRoutesId());
        inspectionTask.setName(request.getTaskName());
        if (StringUtils.isEmpty(inspectionTask.getNumber())) {
            inspectionTask.setNumber(generateTaskNo(DeviceManageEnums.ImageType.DEVICE_INSPECTION.getCode()));
        }
        inspectionTask.setBeginDate(request.getTaskBegin());
        inspectionTask.setEndDate(request.getTaskEnd());
        inspectionTask.setRegular(0);
        inspectionTask.setRegularName("临时");
        inspectionTask.setContent(request.getContent());
        SysUser user = getLoginUser().getUser();
        inspectionTask.setCreatedBy(user.getNickName());
        inspectionTask.setCreateId(user.getUserId());
        inspectionTask.setImageUrlList(request.getImageUrlList());
        inspectionTask.setState(request.getTaskStatus());
        inspectionTask.setType(request.getType());
        return inspectionTask;

    }

    /**
     * ReleaseTask 实体 转 MaintainTasks 实体对象
     *
     * @param request
     * @return
     */
    private MaintainTasks releaseTaskToMaintain(ReleaseTask request) {
        MaintainTasks maintainTasks;
        if (Objects.isNull(request.getMaintain())) {
            maintainTasks = new MaintainTasks();
        } else {
            maintainTasks = request.getMaintain();
        }

        if (Objects.isNull(maintainTasks.getTaskTypeId())) {
            maintainTasks.setTaskTypeId(0);
        }

        maintainTasks.setTaskName(request.getTaskName());
        if (StringUtils.isEmpty(maintainTasks.getTaskNumber())) {
            maintainTasks.setTaskNumber(generateTaskNo(DeviceManageEnums.ImageType.DEVICE_MAINTENANCE.getCode()));
        }
        // maintainTasks.setStaffId(request.getPrincipal());// 负责人ID
        // maintainTasks.setStaffName(request.getPrincipalName());// 负责人 名字
        maintainTasks.setStartTime(request.getTaskBegin());// 任务开始时间
        maintainTasks.setEndTime(request.getTaskEnd());// 任务结束时间
        List<DeviceDetail> devices = request.getDevices();
        if (CollectionUtils.isEmpty(devices)) {
            throw new BaseException("设备列表为空  （devices 列表不能为空）");
        }
        maintainTasks.setDevices(request.getDevices());
        maintainTasks.setContent(request.getContent());
        maintainTasks.setRecommended(request.getRecommended());
        maintainTasks.setImageUrlList(request.getImageUrlList());
        maintainTasks.setStatus(request.getTaskStatus());
        return maintainTasks;
    }

    /**
     * ReleaseTask 实体 转 MaintainTasks 实体对象
     *
     * @param
     * @return
     */
    private ReleaseTask maintainToReleaseTask(MaintainTasks maintainTasks) {
        ReleaseTask releaseTask = new ReleaseTask();
        releaseTask.setTaskType(3);
        releaseTask.setTaskTypeName("保养");
        releaseTask.setId(maintainTasks.getId());
        releaseTask.setTaskName(maintainTasks.getTaskName());
        releaseTask.setPrincipal(maintainTasks.getStaffId());
        releaseTask.setPrincipalName(maintainTasks.getStaffName());
        releaseTask.setTaskBegin(maintainTasks.getStartTime());
        releaseTask.setTaskEnd(maintainTasks.getEndTime());
        releaseTask.setContent(maintainTasks.getContent());
        releaseTask.setRecommended(maintainTasks.getRecommended());
        releaseTask.setTaskNumber(maintainTasks.getTaskNumber());
        releaseTask.setTaskStatus(maintainTasks.getStatus());
        releaseTask.setTaskStatusName(maintainTasks.getStatusName());
        releaseTask.setCreator(maintainTasks.getCreateUserName());
        releaseTask.setCreateId(maintainTasks.getCreateUserId());
        releaseTask.setDevices(maintainTasks.getDevices());
        releaseTask.setMaintain(maintainTasks);
        releaseTask.setImageUrlList(maintainTasks.getImageUrlList());
        return releaseTask;
    }

    private void initializedParam(DeviceChartRequest request) {
        if (TimeDimensionEnum.DAY.getCode().equals(request.getDateType())) { // 日
            request.setChartBeginDate(DateUtils.getTodayTimestamp());
            request.setChartEndDate(DateUtils.getTodayLastMinute());
            request.setDateFormatGroup("%Y-%m-%d %H");
            request.setDateFormatSelect("%H");
        } else if (TimeDimensionEnum.WEEK.getCode().equals(request.getDateType())) { // 周
            Map<String, Date> weekDate = DateUtils.getWeekDate();
            request.setChartBeginDate(weekDate.get("beginDate"));
            request.setChartEndDate(weekDate.get("endDate"));
            request.setDateFormatGroup("%Y-%m-%d");
            request.setDateFormatSelect("%Y-%m-%d");
        } else if (TimeDimensionEnum.MONTH.getCode().equals(request.getDateType())) { // 月
            Map<String, Date> weekDate = DateUtils.getMonthBeginEndDate();
            request.setChartBeginDate(weekDate.get("beginDate"));
            request.setChartEndDate(weekDate.get("endDate"));
            request.setDateFormatGroup("%Y-%m-%d");
            request.setDateFormatSelect("%d");
        } else if (TimeDimensionEnum.YEAR.getCode().equals(request.getDateType())) { // 年
            request.setChartBeginDate(DateUtils.getCurrentFirstOfYear());
            request.setChartEndDate(DateUtils.getCurrentLastOfYear());
            request.setDateFormatGroup("%Y-%m");
            request.setDateFormatSelect("%m");
        } else if (TimeDimensionEnum.DEFINITION.getCode().equals(request.getDateType())) { // 自定义
            if (request.getChartBeginDate() == null || request.getChartEndDate() == null) {
                throw new BaseException(" 日期类型为自定义时 ，开始时间和结束时间不能为空");
            }
            request.setDateFormatGroup("%Y-%m-%d");
            request.setDateFormatSelect("%Y-%m-%d");
        }

    }

    /**
     * 折线图 填充
     *
     * @param request 接口请求实体类
     */
    private Map<String, Long> currentDateMap(DeviceChartRequest request) {
        Map<String, Long> respMap = new LinkedHashMap<>();
        int compare = 0;
        int beginIndex = 1;
        if (TimeDimensionEnum.DAY.getCode().equals(request.getDateType())) { // 日
            compare = 23;
            beginIndex = 0; // 日 要特意设置为0
        } else if (TimeDimensionEnum.WEEK.getCode().equals(request.getDateType())) { // 周
            respMap.put("周一", 0L);
            respMap.put("周二", 0L);
            respMap.put("周三", 0L);
            respMap.put("周四", 0L);
            respMap.put("周五", 0L);
            respMap.put("周六", 0L);
            respMap.put("周日", 0L);
            return respMap;
        } else if (TimeDimensionEnum.MONTH.getCode().equals(request.getDateType())) { // 月
            compare = DateUtils.getDaysOfMonth(new Date());
        } else if (TimeDimensionEnum.YEAR.getCode().equals(request.getDateType())) { // 年
            compare = 12;
        } else if (TimeDimensionEnum.DEFINITION.getCode().equals(request.getDateType())) { // 自定义
            return findEveryDay(request.getBeginDate(), request.getEndDate());
        }
        for (int i = beginIndex; i <= compare; i++) {
            String key = String.valueOf(i);
            if (i < 10) {
                key = "0" + i;
            }
            respMap.put(key, 0L);
        }
        return respMap;
    }


    // todo 生成任务号

    /**
     * 任务定时生成 todo   1. 自动生成任务号
     */
    public void batchGenerateTask() {
        List<MaintenancePlan> maintenancePlans = maintenancePlanDao.queryAll(new MaintenancePlan());
        if (CollectionUtils.isEmpty(maintenancePlans)) {
            return;
        }
        List<MaintainTasks> tasks = new ArrayList<>();
        List<Long> ids = new ArrayList<>();
        for (MaintenancePlan plan : maintenancePlans) {
            if (!DateUtils.isTomorrow(plan.getNextDate())) {
                continue;
            }
            MaintainTasks maintainTasks = new MaintainTasks();
            maintainTasks.setTaskNumber(generateTaskNo(3)); // 任务编号
            maintainTasks.setCreateUserName(plan.getCreateBy()); // 创建人名称
            maintainTasks.setCreateUserId(plan.getCreatedId()); // 创建人id
            maintainTasks.setTaskName(plan.getMaintainName() + "所属任务"); // 任务编号
            maintainTasks.setStartTime(plan.getNextDate());// 保养开始时间
            maintainTasks.setEndTime(plan.getLastDate());// 保养结束时间

            maintainTasks.setItemNum(Math.toIntExact(plan.getItemNum()));// 保养项数
            maintainTasks.setStaffId(plan.getMaintainPerson()); // 员工id
            maintainTasks.setStatus(Math.toIntExact(WorkOrderStatus.SUBMITTED.getCode())); // 状态
            maintainTasks.setPlanId(plan.getId()); // 计划Id
            maintainTasks.setPeriod(plan.getMaintainPeriod()); // 周期
            maintainTasks.setTaskTypeId(1); // 定时任务
            ids.add(plan.getId());
            tasks.add(maintainTasks);
            // 更新plan的下次开始时间
            plan.setNextDate(getNextPeriod(plan.getMaintainPeriod(), plan.getNextDate()));
            plan.setLastDate(getNextPeriod(plan.getMaintainPeriod(), plan.getLastDate()));
        }

        if (CollectionUtils.isEmpty(tasks)) {
            return;
        }
        maintenancePlanDao.insertOrUpdateBatch(maintenancePlans);
        /**
         * 批量新增 任务list
         */
        maintainTasksDao.insertBatch(tasks);
        // 查看符合条件的 任务List
        if (CollectionUtils.isEmpty(ids)) {
            return;
        }
        // 计算出需要新增的 计划新关联的 设备和设备零件
        List<MaintenanceDevice> maintenanceDevices = maintenanceDeviceDao.queryDeviceAndPartsByPlanIds(ids);
        // 把数据放到map中 key为保养计划id  value 为List
        Map<Long, List<MaintenanceDevice>> planDeviceMap = listToMap(maintenanceDevices);
        // 遍历找出所有设备List
        List<MaintainTasksDevice> devices = devicInfoGen(tasks, planDeviceMap);

        /**
         * 2. 批量新增 设备
         */
        maintainTasksDao.insertBatchDevices(devices);

        // 存储 需要insert的设备零件容器
        List<MaintainTasksDeviceParts> devicePartsContainer = new ArrayList<>();
        packTaskParts(devices, devicePartsContainer);
        /**
         * 批量新增零件
         */
        // 设备零件不为空 新增数据
        if (devicePartsContainer.size() > 0) {
            maintainTasksDao.insertBatchParts(devicePartsContainer);
        }
    }

    /**
     * 给零件赋值   maintainDeviceId  零件所属的保养任务关联关系表
     *
     * @param devices
     * @param devicePartsContainer
     */
    private void packTaskParts(List<MaintainTasksDevice> devices, List<MaintainTasksDeviceParts> devicePartsContainer) {
        for (MaintainTasksDevice device : devices) {
            List<MaintainTasksDeviceParts> parts = device.getParts();
            if (CollectionUtils.isEmpty(parts)) {
                continue;
            }
            for (MaintainTasksDeviceParts part : parts) {
                part.setMaintainDeviceId(device.getId());
                devicePartsContainer.add(part);
            }
        }
    }

    /**
     * 封装生成 任务的设备信息 和设备零件信息
     *
     * @param tasks
     * @param planDeviceMap
     */
    private List<MaintainTasksDevice> devicInfoGen(List<MaintainTasks> tasks, Map<Long, List<MaintenanceDevice>> planDeviceMap) {
        List<MaintainTasksDevice> taskDevice = new ArrayList(); // 任务设备信息
        for (MaintainTasks task : tasks) {
            // 计划设备信息
            List<MaintenanceDevice> devices = planDeviceMap.get(task.getPlanId());
            for (MaintenanceDevice device : devices) {
                MaintainTasksDevice maintainTasksDevice = new MaintainTasksDevice();
                maintainTasksDevice.setLocation(device.getLocation());
                maintainTasksDevice.setLocationType(device.getLocationType());
                maintainTasksDevice.setDeviceId(device.getDeviceId());
                maintainTasksDevice.setMaintainTaskId(task.getId());
                maintainTasksDevice.setWorkshopId(device.getWorkshopId());
                List<MaintenanceDeviceParts> planDeviceParts = device.getMaintainDeviceParts();
                if (!CollectionUtils.isEmpty(planDeviceParts)) {
                    List<MaintainTasksDeviceParts> taskParts = new ArrayList<>();
                    for (MaintenanceDeviceParts planDevicePart : planDeviceParts) {
                        MaintainTasksDeviceParts taskpart = new MaintainTasksDeviceParts();
                        taskpart.setPartName(planDevicePart.getPartName());
                        taskpart.setMaintainDeviceId(planDevicePart.getMaintainDeviceId());
                        taskpart.setTaskId(task.getId());
                        taskParts.add(taskpart);

                    }
                    maintainTasksDevice.setParts(taskParts); // 封装零件
                }
                taskDevice.add(maintainTasksDevice); // 封装设备
            }
            // task.setTasksDevices(taskDevice);
        }
        return taskDevice;
    }


    private Map<Long, List<MaintenanceDevice>> listToMap(List<MaintenanceDevice> maintenanceDevices) {
        Map<Long, List<MaintenanceDevice>> planDevicesPartMap = new HashMap();
        for (MaintenanceDevice maintenanceDevice : maintenanceDevices) {
            Long planId = maintenanceDevice.getMaintainPlanId();
            if (planDevicesPartMap.containsKey(planId)) {
                planDevicesPartMap.get(planId).add(maintenanceDevice);
            } else {
                List<MaintenanceDevice> devices = new ArrayList<>();
                devices.add(maintenanceDevice);
                planDevicesPartMap.put(planId, devices);
            }
        }
        return planDevicesPartMap;
    }


    /**
     * 自动生成任务号
     *
     * @return
     */
    @Override
    public String generateTaskNo(Integer taskType) {
        String prefix = "";
        if (DeviceManageEnums.ImageType.DEVICE_REPAIR.getCode().equals(taskType)) {
            prefix = "REP-";
        } else if (DeviceManageEnums.ImageType.DEVICE_MAINTENANCE.getCode().equals(taskType)) {
            prefix = "XJ-";
        } else if (DeviceManageEnums.ImageType.DEVICE_INSPECTION.getCode().equals(taskType)) {
            prefix = "OSC-";
        } else if (DeviceManageEnums.ImageType.DEVICE_PARTS.getCode().equals(taskType)) {
            prefix = "BJ-";
        }
        OrderSequence orderSequence = new OrderSequence();
        maintainTasksDao.sequenceTaskNext(orderSequence);
        String seq = String.format("%07d", orderSequence.getId());
        return prefix + seq;
    }


    @Override
    public List<DeviceDetail> newListByDevice(DeviceDetail device) {
        SysUser user = getLoginUser().getUser();
        if (user.isAdmin()) {
            return maintainTasksDao.newListByDevice(device);
        }
        device.setUserId(user.getUserId());
        return maintainTasksDao.newListByDevice(device);
    }

    @Override
    public List<ComboBoxBody> findGroupComboBox() {
        SysUser user = getLoginUser().getUser();
        List<SysRole> roles = user.getRoles();
        Group group = new Group();
        if (SecurityUtils.getUserId() != null && SecurityUtils.getUserId() != 0) {
            // 筛选自己分组（主要针对管理员）
            group.setUserId(group.getUserId());
        } else {
            for (int i = 0; i < roles.size(); i++) {
                // 租户和用户，只查看自己分组
                if (roles.get(i).getRoleKey().equals("tenant") || roles.get(i).getRoleKey().equals("general")) {
                    group.setUserId(user.getUserId());
                    break;
                }
            }
        }
        return groupService
                .selectGroupList(group)
                .stream()
                .map(d -> new ComboBoxBody(d.getGroupId().intValue(), d.getGroupName()))
                .collect(Collectors.toList());
    }

    @Override
    public List<ComboBoxBody> findProductComboBox() {
        Product product = new Product();
        SysUser user = getLoginUser().getUser();
        // 租户权限
        if (user.isAdmin()) {
            return productService
                    .selectProductList(product)
                    .stream()
                    .map(p -> new ComboBoxBody(p.getProductId().intValue(), p.getProductName()))
                    .collect(Collectors.toList());
        }
        product.setTenantId(user.getUserId());
        return productService
                .selectProductList(product)
                .stream()
                .map(p -> new ComboBoxBody(p.getProductId().intValue(), p.getProductName()))
                .collect(Collectors.toList());
    }

    @Override
    public Map<String, Object> selectNewDeviceByDeviceId(Long deviceId) {
        Map<String, Object> result = new HashMap<>();
        DeviceDetail device = deviceDetailMapper.selectDeviceByDeviceId(deviceId);

        LocalDate begin = LocalDate.now();
        LocalDate end = LocalDate.now();
        begin = begin.plusDays(-begin.getDayOfMonth() + 1);
        end = end.plusDays(-end.getDayOfMonth() + 1).plusMonths(1).plusDays(-1);
        // 设置分数：score
        // 得分（1、优秀100分，2、良好80分，3、一般60分，4、较差30分，5、故障0分）
        Integer score = deviceDetailMapper.findIotDeviceTypeLog(device.getSerialNumber(), begin.toString(), end.toString());
        if (!Objects.isNull(score)) {
            if (score == 0) {
                device.setScore(100);
            }
            if (score <= 5 && score > 0) {
                device.setScore(80);
            }
            if (score <= 15 && score > 5) {
                device.setScore(60);
            }
            if (score <= 25 && score > 15) {
                device.setScore(30);
            }
            if (score > 25) {
                device.setScore(0);
            }
        }

        // 严重告警只要还有一条没处理，未处理（status = 2），则为故障
        List<Integer> integers = deviceDetailMapper.findIotAlertLogByStatus(device.getSerialNumber(), begin.toString(), end.toString());
        if (integers.contains(2)) {
            device.setScore(0);
        }

        // 设备为未激活status = 1则默认为优秀
        if (device.getStatus() == 1) {
            device.setScore(100);
        }
        // 保养任务信息（不会超过三条）
        List<TaskBody> taskBodies = maintenancePlanDao
                .findMaintainTasksByDeviceId(deviceId)
                .stream()
                .limit(3)
                .collect(Collectors.toList());
        if (!taskBodies.isEmpty()) {
            taskBodies.stream().forEach(t -> {
                if (t.getDays() == null || t.getDays() < 0) {
                    t.setDays(0);
                }
            });
            // 计算倒计时天数、上一次保养时间
            device.setDays(taskBodies.get(0).getDays());
            device.setLastEndDate(taskBodies.get(0).getEndDate());
            result.put("taskBodies", taskBodies);
        } else {
            result.put("taskBodies", new ArrayList<>());
        }
        // redis中获取设备状态（物模型值）
        device.setThingsModelValue(JSONObject.toJSONString(thingModelCache.getCacheDeviceStatus(device.getProductId(), device.getSerialNumber())));
        result.putAll(JSONObject.parseObject(JSONObject.toJSONString(device)));
        return result;
    }

    @Override
    public List<MaintainTasksItems> taskItemsList(MaintainTasksItems tasks) {
        MaintainTasksItemsExample ex = new MaintainTasksItemsExample();
        MaintainTasksItemsExample.Criteria criteria = ex.createCriteria();
        if (StringUtils.isNotEmpty(tasks.getItemName())) {
            criteria.andItemNameLike("%" + tasks.getItemName() + "%");
        }
        if (StringUtils.isNotEmpty(tasks.getItemValue())) {
            criteria.andItemValueEqualTo(tasks.getItemValue());
        }
        if (ObjUtil.isNotNull(tasks.getMaintainTaskId())) {
            criteria.andMaintainTaskIdEqualTo(tasks.getMaintainTaskId());
        }
        ex.setOrderByClause(" id desc ");
        return maintainTasksItemsMapper.selectByExample(ex);
    }

    @Override
    public MaintainTasksItems selectMaintainTasksItemsById(Long id) {
        return maintainTasksItemsMapper.selectByPrimaryKey(id);
    }

    @Override
    public int insertMaintainTasksItems(MaintainTasksItems maintainTasksItems) {
        return maintainTasksItemsMapper.insert(maintainTasksItems);
    }

    @Override
    public int updateMaintainTasksItems(MaintainTasksItems maintainTasksItems) {
        return maintainTasksItemsMapper.updateByPrimaryKeySelective(maintainTasksItems);
    }

    @Override
    public int deleteMaintainTasksItemsByIds(Long[] ids) {
        MaintainTasksItemsExample ex = new MaintainTasksItemsExample();
        ex.createCriteria().andIdIn(Arrays.asList(ids));
        return maintainTasksItemsMapper.deleteByExample(ex);
    }

    @Override
    public List<ImageUrl> selectMaintainImgs(MaintainTasks tasks) {
        ImageUrl imageUrl = new ImageUrl();
        imageUrl.setType(DeviceManageEnums.ImageType.DEVICE_MAINTENANCE.getCode());
        imageUrl.setOrderId(tasks.getId());
        imageUrl.setBusType(1);
        return imageUrlDao.queryAll(imageUrl);
    }

    @Override
    public int updateMaintainImgs(MaintainTasks tasks) {
        ImageUrl imgs = new ImageUrl();
        imgs.setOrderId(tasks.getId());
        imgs.setType(DeviceManageEnums.ImageType.DEVICE_MAINTENANCE.getCode());
        imgs.setBusType(1);

        if (Objects.nonNull(tasks.getImageUrlList())) {
            int di = imageUrlDao.deleteByOrderIdType(imgs);
            if (!CollectionUtils.isEmpty(tasks.getImageUrlList())) {
                for (ImageUrl imageUrl : tasks.getImageUrlList()) {
                    if (!StrUtil.isEmpty(imageUrl.getImgUrl())) {
                        imageUrl.setOrderId(tasks.getId());
                        imageUrl.setType(DeviceManageEnums.ImageType.DEVICE_MAINTENANCE.getCode());
                        imageUrl.setBusType(1);
                    }
                }
                return imageUrlDao.insertBatch(tasks.getImageUrlList());
            } else {
                return di;
            }
        }
        return 1;
    }

    @Override
    public List<ImageUrl> selectInspectionImgs(InspectionTask tasks) {
        ImageUrl imageUrl = new ImageUrl();
        imageUrl.setType(DeviceManageEnums.ImageType.DEVICE_INSPECTION.getCode());
        imageUrl.setOrderId(tasks.getId());
        imageUrl.setBusType(1);
        return imageUrlDao.queryAll(imageUrl);
    }

    @Override
    public int updateInspectionImgs(InspectionTask tasks) {
        ImageUrl imgs = new ImageUrl();
        imgs.setOrderId(tasks.getId());
        imgs.setType(DeviceManageEnums.ImageType.DEVICE_INSPECTION.getCode());
        imgs.setBusType(1);

        if (Objects.nonNull(tasks.getImageUrlList())) {
            int di = imageUrlDao.deleteByOrderIdType(imgs);
            if (!CollectionUtils.isEmpty(tasks.getImageUrlList())) {
                for (ImageUrl imageUrl : tasks.getImageUrlList()) {
                    if (!StrUtil.isEmpty(imageUrl.getImgUrl())) {
                        imageUrl.setOrderId(tasks.getId());
                        imageUrl.setType(DeviceManageEnums.ImageType.DEVICE_INSPECTION.getCode());
                        imageUrl.setBusType(1);
                    }
                }
                return imageUrlDao.insertBatch(tasks.getImageUrlList());
            } else {
                return di;
            }
        }
        return 1;
    }

    /**
     * 生命周期的逻辑判断
     */
    @Override
    public void updatelifeCycle(Long DeviceId) {
        // 获取设备详细信息
        DeviceDetail dbDetail = deviceDetailMapper.selectDeviceByDeviceId(DeviceId);
        // 检查设备安装位置是否已设置
        if (dbDetail.getPlacement() == null) {
            //为空则在安装设备中
            updateDeviceLifecyle(DeviceId, 2);
        } else {
            //不为空则在判断是否在维修中
            EquipmentRepair equipmentRepair = new EquipmentRepair();
            equipmentRepair.setEquipmentId(DeviceId);
            // 检查设备是否在维修信息中
            List<EquipmentRepair> equipmentRepairList = equipmentRepairService.queryByPage(equipmentRepair);
            if (!equipmentRepairList.isEmpty()) {
                Optional<EquipmentRepair> latestRepairOptional = equipmentRepairList
                        .stream()
                        .max(Comparator.comparing(EquipmentRepair::getCreateTime));
                latestRepairOptional.ifPresent(latestRepair -> {
                    if (latestRepair.getStatus() == 6) {
                        //维修完成
                        updateDeviceLifecyle(DeviceId, 4);
                    } else {
                        updateDeviceLifecyle(DeviceId, 3);
                    }
                });
                return;
            }
            //还在维修中
            updateDeviceLifecyle(DeviceId, 3);
        }
    }

    @Override
    public void addMaintainLog(MaintainLog maintainLog) {
        maintainTasksDao.addMaintainLog(maintainLog);
    }

    @Override
    public AjaxResult devcioeUpdatelifeCycle(DeviceDetail deviceDetail) {
        AjaxResult ajaxResult = new AjaxResult();
        List<DeviceLifecyle> deviceLifecyleList = maintainTasksDao.getDeviceLifecyle(deviceDetail.getDeviceId());
        ajaxResult.put("data", deviceLifecyleList);
        return ajaxResult;
    }

    @Override
    public List<MaintainLog> selectMaintainLogList(Long deviceId) {
        return maintainTasksDao.selectMaintainLog(deviceId);
    }

    // 更新设备生命周期状态的通用方法
    @Override
    public void updateDeviceLifecyle(Long deviceId, int lifeCycleStatus) {
        DeviceLifecyle deviceLifecyle = new DeviceLifecyle();
        deviceLifecyle.setDeviceId(deviceId);
        deviceLifecyle.setDevcieStatus(lifeCycleStatus);
        maintainTasksDao.updateDeviceLifecyle(deviceLifecyle);
    }

    @Override
    public void addMaintainLogs(String name, Long deviceId) {
        MaintainLog maintainLog = new MaintainLog();
        maintainLog.setDeviceId(deviceId);
        maintainLog.setMaintainlogName(name);
        maintainLog.setCreateBy(getUsername());
        maintainLog.setCreateTime(new Date());
        maintainTasksDao.addMaintainLog(maintainLog);
    }

    @Override
    public List<DeviceLifecyle> getDeviceLifecyle(Long deviceId) {
        return maintainTasksDao.getDeviceLifecyle(deviceId);
    }
}
